# 如何加载 JSON

[JSON（JavaScript 对象表示）](https://en.wikipedia.org/wiki/JSON) 是一种开放标准文件格式和数据交换格式，使用人类可读的文本来存储和传输由属性-值对和数组（或其他可序列化值）组成的数据对象。

[JSON Lines](https://jsonlines.org/) 是一种文件格式，其中每一行都是一个有效的 JSON 值。

LangChain 实现了一个 [JSONLoader](https://api.python.langchain.com/en/latest/document_loaders/langchain_community.document_loaders.json_loader.JSONLoader.html)，用于将 JSON 和 JSONL 数据转换为 LangChain [Document](https://api.python.langchain.com/en/latest/documents/langchain_core.documents.base.Document.html#langchain_core.documents.base.Document) 对象。它使用指定的 [jq schema](https://en.wikipedia.org/wiki/Jq_(programming_language)) 来解析 JSON 文件，允许将特定字段提取到 LangChain Document 的内容和元数据中。

它使用了 `jq` python 包。查看这个 [手册](https://stedolan.github.io/jq/manual/#Basicfilters) 以获取有关 `jq` 语法的详细文档。

这里我们将演示：

- 如何将 JSON 和 JSONL 数据加载到 LangChain `Document` 的内容中；

- 如何将 JSON 和 JSONL 数据加载到与 `Document` 相关的元数据中。

```python
#!pip install jq
```
```python
from langchain_community.document_loaders import JSONLoader
```
```python
import json
from pathlib import Path
from pprint import pprint
```
```python
file_path='./example_data/facebook_chat.json'
data = json.loads(Path(file_path).read_text())
```
```python
pprint(data)
```

## 使用 `JSONLoader`

假设我们有兴趣提取 JSON 数据中 `messages` 键下 `content` 字段中的值。通过 `JSONLoader` 可轻松实现如下。

### JSON 文件

```python
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[].content',
    text_content=False)
data = loader.load()
```
```python
pprint(data)
```

### JSON Lines 文件

如果要从 JSON Lines 文件中加载文档，可以传递 `json_lines=True`，并指定 `jq_schema` 以从单个 JSON 对象中提取 `page_content`。

```python
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
```
```python
loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    jq_schema='.content',
    text_content=False,
    json_lines=True)
data = loader.load()
```
```python
pprint(data)
```

另一个选项是设置 `jq_schema='.'` 并提供 `content_key`：

```python
loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    jq_schema='.',
    content_key='sender_name',
    json_lines=True)
data = loader.load()
```
```python
pprint(data)
```

### 带有 jq schema `content_key` 的 JSON 文件

要使用 jq schema 中的 content_key 从 JSON 文件加载文档，请设置 is_content_key_jq_parsable=True。确保 content_key 兼容并可以使用 jq schema 进行解析。

```python
file_path = './sample.json'
pprint(Path(file_path).read_text())
```
```python
loader = JSONLoader(
    file_path=file_path,
    jq_schema=".data[]",
    content_key=".attributes.message",
    is_content_key_jq_parsable=True,
)
data = loader.load()
```
```python
pprint(data)
```

## 提取元数据

通常，我们希望将 JSON 文件中可用的元数据包含在从内容创建的文档中。

以下演示了如何使用 `JSONLoader` 提取元数据。

需要注意一些关键更改。在之前的示例中，我们没有收集元数据，我们设法直接在模式中指定 `page_content` 的值可以从哪里提取。

```
.messages[].content
```

在当前示例中，我们必须告诉加载器在 `messages` 字段中迭代记录。然后，jq_schema 必须是：

```
.messages[]
```

这允许我们将记录（字典）传递给必须实现的 `metadata_func`。`metadata_func` 负责识别记录中应包含在最终 `Document` 对象中存储的元数据的哪些信息。

此外，现在我们必须通过加载器明确指定 `content_key` 参数，以从记录中的哪个键中提取 `page_content` 的值。

```python
# 定义元数据提取函数。
def metadata_func(record: dict, metadata: dict) -> dict:
    metadata["sender_name"] = record.get("sender_name")```

metadata["timestamp_ms"] = record.get("timestamp_ms")

    return metadata

loader = JSONLoader(

    file_path='./example_data/facebook_chat.json',

    jq_schema='.messages[]',

    content_key="content",

    metadata_func=metadata_func

)

data = loader.load()

```
```python
pprint(data)
```
现在，您会发现文档中包含与我们提取的内容相关的元数据。
## `metadata_func`
如上所示，`metadata_func`接受由`JSONLoader`生成的默认元数据。这允许用户完全控制元数据的格式。
例如，默认元数据包含`source`和`seq_num`键。然而，JSON数据可能也包含这些键。然后，用户可以利用`metadata_func`来重命名默认键并使用JSON数据中的键。
下面的示例显示了如何修改`source`，使其仅包含相对于`langchain`目录的文件源信息。
```python
# 定义元数据提取函数。
def metadata_func(record: dict, metadata: dict) -> dict:
    metadata["sender_name"] = record.get("sender_name")
    metadata["timestamp_ms"] = record.get("timestamp_ms")
    if "source" in metadata:
        source = metadata["source"].split("/")
        source = source[source.index("langchain"):]
        metadata["source"] = "/".join(source)
    return metadata
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)
data = loader.load()
```
```python
pprint(data)
```

## 带有 jq 模式的常见 JSON 结构

下面的列表提供了用户可以根据结构从 JSON 数据中提取内容的可能的 `jq_schema` 参考。

